<?php

namespace app\api\controller\v23;

use app\api\controller\v2\Auth;
use app\common\cachemodel\Fortune;
use app\common\cachemodel\Orders as OrdersCacheModel;
use app\common\cachemodel\OrdersGoods;
use app\common\cachemodel\OrdersLib;
use app\common\cachemodel\Recode;
use app\common\cachemodel\UserCoupon;
use app\common\cachemodel\ZlcrCustomReportGoods;
use app\common\cachemodel\ZlcrCustomReportQuestion;
use app\common\cachemodel\ZlcrCustomReportQuestionInfo;
use app\common\cachemodel\ZlTarotRecords;
use app\common\lib\exception\ApiException;
use app\common\lib\PushQueue;
use app\common\lib\Util;
use Exception;
use think\Cache;
use think\Db;
use think\Log;
use think\response\Json;

/**
 * @version 2.5.2 订单控制器
 * Class Orders
 * @package app\api\controller\v22
 */
class Orders extends Auth
{
    public $msg;

    /**
     * 接口，下单
     * order_type 1=>校准生辰,2=>日运,3=>月运,4=>年运,5=>幸运之城,6=>教学视频,7=>本命预测,8=>vip会员
     * order_id 01=>校准生辰 02=>运势 03=>幸运之城，04=>教学视频，05=>本命预测
     * @return Json
     * @throws Exception
     */
    public function pay_unlock()
    {
        $this->msg = '';
        $param['trade_type'] = input('param.trade_type/d', 0);
        $param['order_type'] = input('param.order_type/d', 0);
        $param['gids'] = input('param.gids/s', '');
        $param['param'] = input('param.param', '');
        $param['openid'] = input('param.openid/s', '');
        //定制报告检测固定问题今日已购买数量
        $customModel = new ZlcrCustomReportGoods();
        $reportNum = $customModel->getGoodsIndexNum();
        if ($param['order_type'] === 15)
        {
            if ($reportNum['switch'] && !$reportNum['num'])
            {
                $pop = [
                    'tips' => "公测阶段每日限量，今日已无购买名额\n请明日再试",
                    'title' => '非常抱歉'
                ];
                return show(config('code.success'), '商品限量', ['pop' => $pop]);
            }
            Cache::set($customModel->custom_report_goods_index_num_cache . date('Ymd'), $reportNum['num'] - 1, 86400);
        }
        $param = OrdersLib::pay_order_param_format($this->user['id'], $param);
        if ($param['trade_type'] === 4)
        {
            return show(config('code.error'), '支付方式错误');
        }
        if ($param['price'] >= 0.01)
        {
            //生成订单数据并下单
            $arr = $this->SaveOrder($param);

            return show(config('code.success'), '下单成功', $arr['data']);
        }
        return show(config('code.error'), '下单金额有误');
    }

    /**
     * 生成订单，并下单
     * @param $param ['order_type','trade_type','rid','cid','reid','gids','goods_info','price'，'start_time','out_trade_no','account','extend','pay_des','openid']
     * @return array|bool|Json
     * @throws Exception
     */
    private function SaveOrder($param)
    {
        $CouponModel = new UserCoupon();
        $orderModel = new OrdersCacheModel();
        $gid = current($param['gids']);
        Db::startTrans();
        try
        {
            //若是运势，则添加运势中间表数据
            if (in_array($param['order_type'], [2, 3, 4], false))
            {
                $middle_res = $this->pay_fortune($param['rid'], $param['start_time'], $param['order_type']);
                if ($middle_res === false)
                {
                    throw new ApiException('下单失败,请重新操作');
                }
            }
            //生成订单数据
            $insert = [
                'order_type' => $param['order_type'],
                'uid' => $this->user['id'],
                'gid' => current($param['gids']),
                'order_id' => $param['out_trade_no'],
                'reid' => $param['reid'],
                'fid' => $middle_res ?? 0,
                'trade_type' => $param['trade_type'],
                'total_amount' => $param['price'],
                'create_time' => $this->request->time(),
                'status' => 0,
                'account' => $param['account'],
                'extend' => $param['extend']
            ];
            // 生成订单到数据库
            $oid = $orderModel->SaveData($insert);
            if ($oid === false)
            {
                throw new ApiException('下单失败,请重新操作');
            }
            //添加中间表数据
            if ($param['rid'])
            {
                $middle_res = $this->insertMiddle($param['rid'], $param['gids'], $oid);
                if ($middle_res === false)
                {
                    throw new ApiException('下单失败,请重新操作');
                }
            }
            //添加定制报告问题记录
            if ($param['order_type'] === 15)
            {
                $questionModel = new ZlcrCustomReportQuestion();
                $questionModel->addCustomReport($insert, $param);
            }
            //塔罗记录更新订单编号数据
            if ($param['order_type'] === 16)
            {
                (new ZlTarotRecords())->updateData($param['history_id'], ['order_num' => $param['out_trade_no']]);
            }
            //修改优惠券状态为已锁定
            if ($param['cid'])
            {
                $res = $CouponModel->use_return($this->user['id'], $param['cid'], ['status' => 4, 'oid' => $oid, 'update_time' => $this->request->time()]);
                if ($res === false)
                {
                    throw new ApiException($CouponModel->getError());
                }
            }
            //检测订单关闭入队
            PushQueue::CloseOrder($param['out_trade_no']);

            //更新订单详情缓存
            $orderModel->UpdateCache($param['out_trade_no'], 0);
            Db::commit();
        }
        catch (Exception $e)
        {
            Db::rollback();
            Log::write('入库失败信息：' . $e->getMessage() . '【' . $e->getFile() . $e->getLine() . '】', 'error');
            throw new ApiException('下单失败,请重新操作');
        }

        //支付订单
        $arr = OrdersLib::unifyPayOrder([
            'oid' => $oid,
            'trade_type' => $param['trade_type'],
            'total_amount' => $param['price'],
            'pay_des' => $param['pay_des'],
            'order_id' => $param['out_trade_no'],
            'openid' => $param['openid'],
            'callback_url' => '',
            'order_type' => $param['order_type']
        ], 1);
        if ($this->headers['app-type'] === 'ios')
        {
            $new_gid = [];
            foreach ($param['gids'] as $gid)
            {
                $new_gid[] = 'apple_pay_' . $gid;
            }
            $skuId = implode(',', $new_gid);
            $arr['data']['skuId'] = $skuId;
        }
        return $arr;
    }

    /**
     * 运势下单
     * @param int $rid
     * @param int $start_time
     * @param int $order_type
     * @return bool|int|string
     */
    private function pay_fortune($rid, $start_time, $order_type)
    {
        $arr = [
            'type' => $order_type - 1,
            'rids' => $rid,
            'time' => $start_time,
            'create_time' => $this->request->time(),
        ];
        return (new Fortune())->insertGetId($arr); //每日运势id
    }

    /**
     * 添加中间表数据
     * @param $rid
     * @param $gids
     * @param $oid
     * @return bool
     */
    private function insertMiddle($rid, $gids, $oid)
    {
        $array = [];
        foreach ($gids as $k => $v)
        {
            $array[] = [
                'gid' => $v,
                'oid' => $oid,
                'rid' => $rid
            ];
        }
        //中间表
        (new OrdersGoods())->insertAll($array);
    }
}
